import sqlite3
import yaml
import os
import glob
import sys
import re
from time import strftime
from PySide6.QtGui import QAction
from Ui_mainWindow import Ui_MainWindow
from Ui_settings import Ui_settingWindow
from PySide6.QtCore import QFile, Qt, Signal
from PySide6.QtWidgets import (QApplication, QMainWindow, QMessageBox, QWidget, QDialog, QAbstractItemView, QFileDialog,
                               QTableWidget, QTableWidgetItem)

# 可考虑用富文本框做链接，写入markdown


class settingWindow(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.parent = parent
        self.ui_settingWindow = Ui_settingWindow()
        self.ui_settingWindow.setupUi(self)
        self.bind()

    def bind(self):
        self.ui_settingWindow.setting_save.clicked.connect(self.save)
        self.ui_settingWindow.setting_path.clicked.connect(self.path)

    def save(self):
        path = self.ui_settingWindow.setting_svnEdit.text()
        account = self.ui_settingWindow.setting_accountEdit.text()
        if (path == "" or account == ""):
            QMessageBox(self).warning(None, "提示", "请输入正确内容, 保证用户名和SVN地址非空")
            return
        try:
            with open("settings.yaml", "w+") as f:
                yaml.dump({"SVN": path, "name": account}, f)
            QMessageBox(self).warning(None, "提示", "保存成功")
            self.parent.svnPath = path
            self.parent.userName = account
            self.parent.ConDbs()
            self.parent.settingWindowClose()
        except:
            QMessageBox(self).warning(
                None, "提示", "保存失败, 重试或删除settings.yaml文件后再试")

    def path(self):  # 打开文件选择器
        selectPath = QFileDialog.getExistingDirectory(self, "设置SVN路径",)
        self.ui_settingWindow.setting_svnEdit.setText(selectPath)


class MainWindow(QMainWindow):
    def __init__(self):
        self.dbSelf = None
        self.svnPath = ""
        self.userName = ""
        self.dbsConn = dict()
        super(MainWindow, self).__init__()
        self.mainWindow = Ui_MainWindow()
        self.mainWindow.setupUi(self)
        # self.Regist()
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.ActionsContextMenu)
        self.openSettingWindowAc = QAction("设置")
        self.updateSvnAc = QAction("更新")
        self.uploadSvnAc = QAction("上传")
        self.addActions([self.openSettingWindowAc,
                        self.updateSvnAc, self.uploadSvnAc])
        self.mainWindow.addTabW.setContextMenuPolicy(
            Qt.ContextMenuPolicy.ActionsContextMenu)
        self.addTabWDel = QAction("删除")
        self.addTabWShow = QAction("预览")
        self.mainWindow.addTabW.addActions([self.addTabWDel, self.addTabWShow])
        self.mainWindow.resultTbW.setSortingEnabled(True)
        self.mainWindow.resultTbW.setColumnCount(3)
        self.mainWindow.addTabW.setColumnCount(2)
        self.bind()

    def bind(self):
        self.updateSvnAc.triggered.connect(self.updateSvn)
        self.uploadSvnAc.triggered.connect(self.uploadSvn)
        self.openSettingWindowAc.triggered.connect(self.settingWindowShow)
        self.addTabWDel.triggered.connect(self.addTableDelete)
        self.addTabWShow.triggered.connect(self.addTabWShowCurRow)
        self.mainWindow.searchBtn.clicked.connect(self.searchDb)
        self.mainWindow.addLineEd.textChanged.connect(
            self.ShowLineEditContent)
        self.mainWindow.addBtn.clicked.connect(self.AddContent)
        self.mainWindow.addTextEd.textChanged.connect(
            self.ShowTextEditContent)
        self.mainWindow.cancelBtn.clicked.connect(self.cancel)
        self.mainWindow.saveAllBtn.clicked.connect(self.saveAllConent)
        self.mainWindow.addTabW.itemClicked.connect(self.addTabWShowCurRow)
        self.mainWindow.resultTbW.itemClicked.connect(self.resultTbWShowCurRow)

    def resultTbWShowCurRow(self):
        keyword = self.mainWindow.resultTbW.item(curRow, 1).text()
        curRow = self.mainWindow.resultTbW.currentRow()
        self.mainWindow.resLineEd.setText(keyword)
        desc = self.mainWindow.resultTbW.item(curRow, 2).text()
        desc = desc.replace("$(svn)", self.svnPath)
        self.mainWindow.resTexEd.setMarkdown(desc)

    def saveAllConent(self):
        CreatTableCreatSql = """CREATE TABLE IF NOT EXISTS duneComShare (
            keyword TEXT,
            describe TEXT
            data TEXT)"""
        cursor = self.dbSelf.cursor()
        with self.dbSelf:
            cursor.execute(CreatTableCreatSql)
        rowCount = self.mainWindow.addTabW.rowCount()
        sqlCountStr = "SELECT COUNT(keyword) FROM duneComShare WHERE keyword=?"
        sqlInsertStr = "INSERT INTO duneComShare VALUES(?, ?, ?)"
        isExist = False
        dataTime = strftime("%Y%m%d%H%M%S")[2:]
        for row in range(rowCount):
            keyword = self.mainWindow.addTabW.item(row, 0).text()
            data = cursor.execute(sqlCountStr, (keyword, ))
            
            if (data.fetchone()[0] > 0):
                isExist = True
                continue
            desc = self.mainWindow.addTabW.item(row, 1).text()
            cursor.execute(sqlInsertStr, (keyword, desc, dataTime))
            self.mainWindow.addTabW.removeRow(row)
        self.dbSelf.commit()
        if (isExist):
            answer = QMessageBox(self).warning(None, "提示", "剩余部分条目在当前数据库中已存在，是否直接覆盖？",
                                               QMessageBox.No | QMessageBox.Yes)
            if (answer == QMessageBox.Yes):
                sqlUpdataStr = "UPDATE duneComShare SET describe=? data=? WHERE keyword=?"
                for row in range(self.mainWindow.addTabW.rowCount()):
                    keyword = self.mainWindow.addTabW.item(row, 0).text()
                    desc = self.mainWindow.addTabW.item(row, 1).text()
                    cursor.execute(
                        sqlUpdataStr, (desc, dataTime, keyword))
                    self.mainWindow.addTabW.removeRow(row)
                self.dbSelf.commit()

    def cancel(self):
        curRow = self.mainWindow.addTabW.currentRow()
        if (curRow < 0):
            return
        addText = self.mainWindow.addTextEd.toPlainText()
        addLine = self.mainWindow.addLineEd.text()
        isAdd = True
        if ((addText != "") or (addLine != "")):
            # QMessageBox(self).warning(None,"提示", QMessageBox.No | QMessageBox.Yes)
            answer = QMessageBox(self).warning(None, "提示", "编辑框中还有内容未保存, 是否先添加至列表?",
                                               QMessageBox.No | QMessageBox.Yes)
            if (answer == QMessageBox.Yes):
                isAdd = self.AddContent()
        if (isAdd):
            self.mainWindow.addLineEd.setText(
                self.mainWindow.addTabW.item(curRow, 0).text())
            self.mainWindow.addTextEd.setPlainText(
                self.mainWindow.addTabW.item(curRow, 1).text())
            self.mainWindow.addTabW.removeRow(curRow)

    def addTabWShowCurRow(self):
        curRow = self.mainWindow.addTabW.currentRow()
        keyword = self.mainWindow.addTabW.item(curRow, 0).text()
        self.ShowLineEditContent(keyword)
        descText = self.mainWindow.addTabW.item(curRow, 1).text()
        descText = descText.replace("$(svn)", self.svnPath)
        self.mainWindow.showTextEd.setMarkdown(descText)

    def addTableDelete(self):
        curRow = self.mainWindow.addTabW.currentRow()
        self.mainWindow.addTabW.removeRow(curRow)

    def searchAll(self, authorList, authorName):
        res = []
        countAll = 0
        sqlSelectAllStr = "SELECT * FROM duneComShare"
        for i in range(len(authorList)):
            tempData = [authorName[i]]
            con = authorList[i]
            keyData = con.execute(sqlSelectAllStr)
            tempData += keyData.fetchall()  # 这里是为了把作者的姓名组合到结果的第一个去
            countAll += len(tempData) - 1  # 减1是为了把名字的长度去除
            res.append(tempData)
        return res, countAll
    def searchContent(self, authorList, authorName):
        res = []
        countAll = 0
        sqlSelectKeyStr = "SELECT * FROM duneComShare WHERE keyword LIKE ?  OR describe LIKE ?"
        for i in range(len(authorList)):
            tempData = [authorName[i]]
            con = authorList[i]
            keyData = con.execute(sqlSelectKeyStr, (self.mainWindow.searchLineEd.text(
            ), self.mainWindow.searchLineEd.text()))
            tempData += keyData.fetchall()  # 这里是为了把作者的姓名组合到结果的第一个去
            countAll += len(tempData) - 1  # 减1是为了把名字的长度去除
            res.append(tempData)
        return res, countAll
    # 使用正则来搜索，这里要重写

    def searchDb(self):
        author = self.mainWindow.authorList.currentText()
        if (author != "ALL"):
            authorList = [self.dbsConn[author]]
            authorName = [author]
        else:
            authorList = list(self.dbsConn.values())
            authorName = [self.mainWindow.authorList.itemText(
                i) for i in range(self.mainWindow.authorList.count())]
        if (self.mainWindow.searchLineEd.text() == ""):
            res, countAll = self.searchAll(authorList, authorName)
        else:
            res, countAll = self.searchContent(authorList, authorName)
        self.mainWindow.resultTbW.setRowCount(countAll)
        lineCount = 0
        for ans in res:
            self.mainWindow.resultTbW.setItem(
                lineCount, 0, QTableWidgetItem(ans[0]))
            for i in range(1, len(ans)):
                self.mainWindow.resultTbW.setItem(
                    lineCount, 1, QTableWidgetItem(ans[i][0]))
                self.mainWindow.resultTbW.setItem(
                    lineCount, 2, QTableWidgetItem(ans[i][1]))
                lineCount += 1

    def updateSvn(self):
        print("not support")

    def uploadSvn(self):
        print('not support')

    def IsRegist(self):
        with open("settings.yaml", "r") as f:
            data = yaml.load(f, Loader=yaml.FullLoader)
            if (data['name'] != "l00806702") or (data["SVN"] == None):
                return False
        self.svnPath = data["SVN"]
        self.userName = data["name"]
        self.ConDbs()
        return True

    def settingWindowShow(self):
        self.settingWindow = settingWindow(self)
        self.settingWindow.setWindowModality(Qt.ApplicationModal)
        self.settingWindow.show()

    def settingWindowClose(self):
        if (self.settingWindow == None):
            return
        self.settingWindow.close()
        self.settingWindow = None

    def Regist(self):
        if(self.IsRegist()):  # 已正常注册
            return
        QMessageBox(self).warning(None, "提示", "请正确设置用户和地址信息")
        self.settingWindowShow()

    # conDbs方法改tableView重写
    def ConDbs(self):
        pdfPath = self.svnPath + "/*.db"
        dbFiles = glob.glob(pdfPath)
        if (dbFiles):
            self.mainWindow.authorList.clear()
            self.mainWindow.authorList.addItem("ALL")
        for nameAll in dbFiles:
            # -1取分割后的最后一个，即带有文件名的内容，再以点分割去除掉文件后缀得到用户名
            fileName = nameAll.split("\\")[-1]
            userName = fileName.split(".")[0]
            self.mainWindow.authorList.addItem(userName)
            self.dbsConn[userName] = sqlite3.connect(nameAll)  # 此处会连接所有已知的数据库
        # 此处连接个人数据库用于新增指令
        if (self.userName in self.dbsConn):
            self.dbSelf = self.dbsConn[self.userName]
        else:
            self.dbSelf = sqlite3.connect(self.userName+".db")

    def ShowTextEditContent(self):
        textEditData = self.mainWindow.addTextEd.toPlainText()
        textEditData = textEditData.replace("$(svn)", self.svnPath)
        self.mainWindow.showTextEd.setMarkdown(textEditData)

    def ShowLineEditContent(self, text):
        # self.mainWindow.showLineEd.setText(self.mainWindow.addLineEd.text())
        self.mainWindow.showLineEd.setText(text)

    def AddContent(self):
        addText = self.mainWindow.addTextEd.toPlainText()
        addLine = self.mainWindow.addLineEd.text()
        if ((addText == "") or (addLine == "")):
            QMessageBox(self).warning(None, "提示", "需要同时补全关键字和描述才可以添加")
            return False
        rowcount = self.mainWindow.addTabW.rowCount()
        self.mainWindow.addTabW.setRowCount(rowcount+1)
        self.mainWindow.addTabW.setItem(rowcount, 0, QTableWidgetItem(addLine))
        self.mainWindow.addTabW.setItem(rowcount, 1, QTableWidgetItem(addText))
        self.mainWindow.addTextEd.clear()
        self.mainWindow.addLineEd.clear()
        return True


if __name__ == "__main__":

    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    mainWindow.Regist()

    sys.exit(app.exec())
